#include <iostream>
#include <istream>
#include <limits>
#include <ostream>

using std::cout;
using std::endl;
using std::cin;

//i^2 = -1

class Complex
{
public:
    Complex(double dreal = 0.0, double dimag = 0.0)
    : _dreal(dreal)
    , _dimag(dimag)
    {
        cout << "Complex(double = 0.0, double = 0.0)" << endl;
    }

    ~Complex()
    {
        cout << "~Complex()" << endl;
    }

    //cout << com1;
    //隐含了this指针
    /* com1 << cout; */
    //输出流运算符函数是不能以成员函数的形式进行重载的，因为如果以
    //成员函数进行重载，那么会多一个隐含的this指针，也就是操作数的
    //个数不对，但是如果将rhs去掉了，那么第一个参数就是this指针，
    //第二个参数就是流os对象，那么就会改变操作数的顺序，所以
    //输出流运算符函数不能以成员函数的形式进行重载
    friend std::ostream &operator<<(std::ostream &os, const Complex &rhs);
    friend std::istream &operator>>(std::istream &is, Complex &rhs);
    //cin >> com;
private:
    double _dreal;
    double _dimag;
};

std::ostream &operator<<(std::ostream &os, const Complex &rhs)
{
    if((0 == rhs._dreal) && (0 == rhs._dimag))
    {
        os << 0 << endl;
    }
    else if(0 == rhs._dreal)
    {
        os  << rhs._dimag << "i" << endl;
    }
    else
    {
        os << rhs._dreal;
        if(rhs._dimag > 0)
        {
            os << " + " << rhs._dimag << "i" << endl;
        }
        else if(0 == rhs._dimag)
        {
            os << endl;
        }
        else
        {
            os << " - " << (-1) *rhs._dimag << "i" << endl;
        }
    }

    return os;
}

void readDouble(std::istream &is, double &number)
{
    while(is >> number, !is.eof())
    {
        if(is.bad())
        {
            std::cerr << "The stream is bad" << endl;
            return;
        }
        else if(is.fail())
        {
            is.clear();
            is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cout << "pls input double data" << endl;
        }
        else
        {
            cout << "number = " << number << endl;
            break;
        }
    }
}

std::istream &operator>>(std::istream &is, Complex &rhs)
{
    /* is >> rhs._dreal >> rhs._dimag; */
    readDouble(is, rhs._dreal);
    readDouble(is, rhs._dimag);
    return is;
}
void test()
{
    Complex com1(2, 3);
    cout << "com1 = " << com1 << endl;
    /* operator<<(operator<<(cout, "com1 = "), com1).operator<<(endl); */
    /* operator<<(cout, "com1 = "); */
    /* operator<<(cout, com1); */
    /* cout.operator<<(endl); */

    cout << endl;
    Complex com2;
    cin >> com2;
    cout << "com2 = " << com2 << endl;

}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

